﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gol.Domain
{
    public class CellGrid
    {
        
        private Cell[,] Cells { get;  set; }

        public int NumberOfRows
        {

            get { return this.Cells.GetLength(0); }
        }
        public int NumberOfColums
        {

            get { return this.Cells.GetLength(1); }
        }

        public Cell this[int x, int y]
        {
            get
            {
                return Cells[x,y];
            }

            set
            {
                Cells[x, y] = value;
            }
        }

        public int CalculateNumberOfNeighboursForCell(int x, int y)
        {
            return this.MakeExtendedCell(x, y).NumberOfneighbours();
        }

     

        public CellGrid(int x, int y)
        {
            Cells = new Cell[x, y];
            for (int i = 0; i < this.NumberOfRows; i++)
            {
                for (int j = 0; j < this.NumberOfColums; j++)
                {
                    Cells[i, j] = new Cell();
                }
            }
        }

       public void Reset()
       {
           for (int i = 0; i < this.NumberOfRows; i++)
           {
               for (int j = 0; j < this.NumberOfColums; j++)
               {
                   Cells[i, j].IsAlive=false;
               }
           }
       }


        public void Intialize(int[,] indexes)
        {

  

            for (int i = 0; i < indexes.GetLength(0); i++)
            {
                var row = indexes[i,0];
                if (row > this.Cells.GetUpperBound(0)) throw new ArgumentOutOfRangeException("indexes", " row to high");
                var col = indexes[i, 1];
                if (col > this.Cells.GetUpperBound(1)) throw new ArgumentOutOfRangeException("indexes", " column to high");
                this.Cells[row, col].IsAlive = true;
            }

       

        }

  
        private ExtendedCell MakeExtendedCell(int x, int y)
        { 
            var extendedCell = new ExtendedCell();

            var indexColMax = Cells.GetUpperBound(1);
            var indexRowMax = Cells.GetUpperBound(0) ;
            if(x==0)
            {
                if (y==0)
                {
                extendedCell.Cells[0, 0].IsAlive = false;
                extendedCell.Cells[0, 1].IsAlive = false;
                extendedCell.Cells[0, 2].IsAlive = false;
                extendedCell.Cells[1, 0].IsAlive = false;
                extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive; 
                extendedCell.Cells[1, 2].IsAlive = this.Cells[x, y+1].IsAlive;
                extendedCell.Cells[2, 0].IsAlive = false;
                extendedCell.Cells[2, 1].IsAlive = this.Cells[x+1, y ].IsAlive;
                extendedCell.Cells[2, 2].IsAlive = this.Cells[x + 1, y+1].IsAlive;
                }
                else if (y==indexColMax)
                {
                    extendedCell.Cells[0, 0].IsAlive = false;
                    extendedCell.Cells[0, 1].IsAlive = false;
                    extendedCell.Cells[0, 2].IsAlive = false;
                    extendedCell.Cells[1, 0].IsAlive = this.Cells[x, y-1].IsAlive;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = false;
                    extendedCell.Cells[2, 0].IsAlive = this.Cells[x + 1, y-1].IsAlive;
                    extendedCell.Cells[2, 1].IsAlive = this.Cells[x + 1, y].IsAlive;
                    extendedCell.Cells[2, 2].IsAlive =false;
                }
                else
                {
                    extendedCell.Cells[0, 0].IsAlive = false;
                    extendedCell.Cells[0, 1].IsAlive = false;
                    extendedCell.Cells[0, 2].IsAlive = false;
                    extendedCell.Cells[1, 0].IsAlive = this.Cells[x, y - 1].IsAlive;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = this.Cells[x, y+1].IsAlive;
                    extendedCell.Cells[2, 0].IsAlive = this.Cells[x + 1, y - 1].IsAlive;
                    extendedCell.Cells[2, 1].IsAlive = this.Cells[x + 1, y].IsAlive;
                    extendedCell.Cells[2, 2].IsAlive = this.Cells[x + 1, y+1].IsAlive;
                }

            }
            else if (x == indexRowMax)
            {
                if (y == 0)
                {
                    extendedCell.Cells[0, 0].IsAlive = false;
                    extendedCell.Cells[0, 1].IsAlive = this.Cells[x-1, y].IsAlive; 
                    extendedCell.Cells[0, 2].IsAlive = this.Cells[x - 1, y+1].IsAlive;
                    extendedCell.Cells[1, 0].IsAlive = false;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = this.Cells[x, y + 1].IsAlive;
                    extendedCell.Cells[2, 0].IsAlive = false;
                    extendedCell.Cells[2, 1].IsAlive =false;
                    extendedCell.Cells[2, 2].IsAlive = false;
                }
                else if (y == indexColMax)
                {
                    extendedCell.Cells[0, 0].IsAlive = this.Cells[x-1, y-1].IsAlive;
                    extendedCell.Cells[0, 1].IsAlive = this.Cells[x-1, y].IsAlive;
                    extendedCell.Cells[0, 2].IsAlive = false;
                    extendedCell.Cells[1, 0].IsAlive = this.Cells[x, y - 1].IsAlive;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = false;
                    extendedCell.Cells[2, 0].IsAlive = false;
                    extendedCell.Cells[2, 1].IsAlive = false;
                    extendedCell.Cells[2, 2].IsAlive = false;
                }
                else
                {
                    extendedCell.Cells[0, 0].IsAlive = this.Cells[x-1, y - 1].IsAlive;
                    extendedCell.Cells[0, 1].IsAlive = this.Cells[x-1, y ].IsAlive;
                    extendedCell.Cells[0, 2].IsAlive = this.Cells[x-1, y+ 1].IsAlive;
                    extendedCell.Cells[1, 0].IsAlive = this.Cells[x, y - 1].IsAlive;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = this.Cells[x, y + 1].IsAlive;
                    extendedCell.Cells[2, 0].IsAlive = false;
                    extendedCell.Cells[2, 1].IsAlive = false;
                    extendedCell.Cells[2, 2].IsAlive = false;
                }
            }
            else
            {
                if (y == 0)
                {
                    extendedCell.Cells[0, 0].IsAlive = false;
                    extendedCell.Cells[0, 1].IsAlive = this.Cells[x - 1, y].IsAlive;
                    extendedCell.Cells[0, 2].IsAlive = this.Cells[x - 1, y + 1].IsAlive;
                    extendedCell.Cells[1, 0].IsAlive = false;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = this.Cells[x, y + 1].IsAlive;
                    extendedCell.Cells[2, 0].IsAlive = false;
                    extendedCell.Cells[2, 1].IsAlive = this.Cells[x+1, y ].IsAlive;
                    extendedCell.Cells[2, 2].IsAlive = this.Cells[x+1, y + 1].IsAlive;
                }
                else if (y == indexColMax)
                {
                    extendedCell.Cells[0, 0].IsAlive = this.Cells[x - 1, y - 1].IsAlive;
                    extendedCell.Cells[0, 1].IsAlive = this.Cells[x - 1, y].IsAlive;
                    extendedCell.Cells[0, 2].IsAlive = false;
                    extendedCell.Cells[1, 0].IsAlive = this.Cells[x, y - 1].IsAlive;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = false;
                    extendedCell.Cells[2, 0].IsAlive = false;
                    extendedCell.Cells[2, 1].IsAlive = false;
                    extendedCell.Cells[2, 2].IsAlive = false;
                }
                else
                {
                    extendedCell.Cells[0, 0].IsAlive = this.Cells[x - 1, y - 1].IsAlive;
                    extendedCell.Cells[0, 1].IsAlive = this.Cells[x - 1, y].IsAlive;
                    extendedCell.Cells[0, 2].IsAlive = this.Cells[x - 1, y + 1].IsAlive;
                    extendedCell.Cells[1, 0].IsAlive = this.Cells[x, y - 1].IsAlive;
                    extendedCell.Cells[1, 1].IsAlive = this.Cells[x, y].IsAlive;
                    extendedCell.Cells[1, 2].IsAlive = this.Cells[x, y + 1].IsAlive;
                    extendedCell.Cells[2, 0].IsAlive = this.Cells[x+1, y - 1].IsAlive;
                    extendedCell.Cells[2, 1].IsAlive = this.Cells[x+1, y].IsAlive;
                    extendedCell.Cells[2, 2].IsAlive = this.Cells[x+1, y + 1].IsAlive;
                }
            }
            
 
            return extendedCell;
        }
    }
}
